#include "ethernet.h"
#include "utils.h"
#include "driver.h"
#include "arp.h"
#include "ip.h"
/**
 * @brief 处理一个收到的数据包
 * 
 * @param buf 要处理的数据包
 */
#define BUF_MIN_LEN 46
#define ETH_HEAD_LEN 14

void ethernet_in(buf_t *buf)
{
    if (buf->len<ETH_HEAD_LEN)
    {   
        return;
    }
    // 先取出eth头，用于获得协议
    ether_hdr_t *hdr = (ether_hdr_t *)buf->data;
    buf_remove_header(buf,sizeof(ether_hdr_t));

    net_in(buf,swap16(hdr->protocol16),hdr->src);
}
/**
 * @brief 处理一个要发送的数据包
 * 
 * @param buf 要处理的数据包
 * @param mac 目标MAC地址
 * @param protocol 上层协议
 */
void ethernet_out(buf_t *buf, const uint8_t *mac, net_protocol_t protocol)
{
    if (buf->len<BUF_MIN_LEN)
    {   
        buf_add_padding(buf,BUF_MIN_LEN-buf->len);
    }
    buf_add_header(buf, sizeof(ether_hdr_t));
    ether_hdr_t *hdr = (ether_hdr_t *)buf->data;
    // 填充目的mac地址
    // 填充源目的地址
    for (size_t i = 0; i < NET_MAC_LEN; i++)
    {
        hdr->dst[i]=mac[i];
    }
    // 这里有个大大的陷阱，如果使用int，占用四个字节，会导致0x11占用四个字节变成11 00，而本应是11，故在pacp的比对中会出错。
    uint8_t src_mac[6] =NET_IF_MAC;
    memcpy(hdr->src,src_mac,sizeof(uint8_t)*NET_MAC_LEN);
    // 这里需要判断填充的时长度还是协议号吗 
    // if (protocol>0x0600)
    // {
    //     hdr->protocol16=protocol;
    // }
    // else{
    //     hdr->protocol16=buf->len;
    // }
    hdr->protocol16=swap16(protocol);
    driver_send(buf);
}
/**
 * @brief 初始化以太网协议
 * 
 */
void ethernet_init()
{
    buf_init(&rxbuf, ETHERNET_MAX_TRANSPORT_UNIT + sizeof(ether_hdr_t));
}

/**
 * @brief 一次以太网轮询
 * 
 */
void ethernet_poll()
{
    if (driver_recv(&rxbuf) > 0)
        ethernet_in(&rxbuf);
}
